阿里云Elasticsearch AI场景语义搜索
阿里云检索服务Elasticsearch版(简称ES)结合了搜索开放平台的组件化模型能力,可以用于构建高效、精准的语义搜索系统。本文介绍搭建AI语义搜索的方法,带您体验AI技术如何提升搜索的准确性和用户体验。
前提条件
已创建阿里云ES 8.13及以上版本实例。本文以8.15版本为例。具体操作,请参见创建阿里云Elasticsearch实例。
已开通阿里云搜索开放平台并创建AI推理模型。
8.15及以上版本,在ES实例控制台自动创建AI模型。具体操作,请参见创建AI推理模型。
8.13版本,在Kibana中通过代码创建AI模型。更多信息,请参见创建和调用Inference APIs。
已登录ES实例的Kibana控制台。具体操作,请参见登录Kibana控制台。
您可以在Kibana控制台的开发工具(Dev Tools)上执行本文中出现的所有代码。
操作流程
AI场景语义搜索包括数据写入和数据查询两个核心步骤。具体原理,请参见AI语义搜索。操作流程包括:
AI模型调试:验证模型是否可以成功调用。
数据处理与写入:
配置ingest pipeline:配置可以对数据进行预处理的ingest pipeline,应用文档切片模型对源数据进行语义切分,应用向量化模型生成文档片段的稠密与稀疏向量。
创建索引:在ES中建立基于向量的文档索引。
写入数据:将源数据写入索引作为搜索内容的基础。
数据查询:
Knn查询:将Query转化为稠密向量进行稠密向量检索。
RRF查询:将Query转化为稠密向量及稀疏向量,并进行全文检索、稠密向量检索、稀疏向量检索,通过融合排序算法召回Top 10的内容。
本文演示了2个ES语义搜索示例:
不使用文档切片:根据写入的文本,直接生成embedding、sparse_embedding字段。
使用文档切片:使用ES nested类型,将一个文本切成多个chunk数组,分别对这些chunk进行embedding、sparse_embedding。
操作步骤(不使用文档切片)
步骤一:(可选)调试模型
调试doc_split推理模型。
POST _inference/doc_split/ops-document-split-001 { "input":["文档切片服务(ops-document-split-001):提供通用文本切片服务,支持基于文档段落、文本语义、指定规则,对HTML、Markdown、txt格式的结构化数据进行拆分,同时支持以富文本形式提取文档中的代码、图片以及表格。OpenSearch文本向量化服务-001(ops-text-embedding-001)提供多语言(40+)文本向量化服务,输入文本最大长度300,输出向量维度1536维。"] }
调试text_embedding推理模型。
POST _inference/text_embedding/ops-text-embedding-001 { "input":["科学技术是第一生产力", "elasticsearch产品文档"] }
调试sparse_embedding推理模型。
POST _inference/sparse_embedding/ops-text-sparse-embedding-001 { "input":["科学技术是第一生产力", "elasticsearch产品文档"] }
步骤二:配置ingest pipeline
文档原始数据长度较小,或已完成文档切片的doc,在向量模型最大处理限制之内,可不使用文档切片,只对写入的内容进行text dense embedding和sparse embedding,配置的ingest pipeline示例如下:
PUT _ingest/pipeline/os-pipeline-no-split-demo
{
"description": "This is an example of text-embedding and sparse-embedding fields",
"processors": [
{
"text_embedding": {
"model_id": "ops-text-embedding-001",
"input_output": [
{
"input_field": "content",
"output_field": "content_embedding"
}
]
}
},
{
"text_embedding": {
"model_id": "ops-text-sparse-embedding-001",
"input_output": [
{
"input_field": "content",
"output_field": "content_sparse_embedding"
}
]
}
}
]
}
ingest pipeline创建成功后,可以通过simulate接口(仅用于模拟调试,不会实际创建索引),测试pipeline处理的效果:
POST _ingest/pipeline/os-pipeline-no-split-demo/_simulate
{
"docs": [
{
"_index": "testindex",
"_id": "1",
"_source":{
"content": "elasticsearch产品文档"
}
}
]
}
步骤三:创建索引
执行以下代码,创建不使用文档切片的索引:
PUT os_demo_no_split_index
{
"mappings": {
"properties": {
"content": {
"type": "text"
},
"content_embedding":{
"type": "dense_vector",
"dims": 1536
},
"content_sparse_embedding":{
"type": "sparse_vector"
}
}
}
}
步骤四:写入数据
将通过pipeline处理后的数据写入索引作为搜索内容基础。
写入数据时带上配置好的pipeline_id,文本数据就可以通过pipeline进行自动的embedding。
POST os_demo_no_split_index/_bulk?pipeline=os-pipeline-no-split-demo
{"index":{}}
{"content":"现代科技的发展推动了人工智能的极速进步。AI在各个领域展现出巨大的潜力,从医疗到金融,AI都在发挥着重要的作用,为人类的生活带来了翻天覆地的变化。"}
{"index":{}}
{"content":"教育是一个国家发展的基石。高质量的教育不仅能够帮助个人实现梦想,还能推动社会的进步。教育公平是实现社会和谐的关键,每个孩子都有受教育的权利。"}
{"index":{}}
{"content":"旅游可以让人们开阔视野,体验不同的文化和风俗。无论是饱览自然风光,还是探寻历史古迹,旅行都能让人们在体验中学习和成长。"}
{"index":{}}
{"content":"健康饮食对于保持身体健康至关重要。合理搭配膳食,摄入足够的营养,不仅可以增强免疫力,还能预防多种疾病。多吃蔬菜水果,少吃高脂食物,是保持健康的重要措施。"}
{"index":{}}
{"content":"互联网改变了人们的生活方式。随着智能手机和社交媒体的普及,信息传播的速度大大加快。人们可以通过网络获取最新的新闻、学习新的知识,以及与朋友保持联系。"}
{"index":{}}
{"content":"历史是一面镜子,通过研究历史,人们能够更好地了解过去,从而预测未来。无论是战争的经验教训,还是文明的更迭,历史都为我们提供了宝贵的知识和智慧。"}
{"index":{}}
{"content":"运动是保持身体健康的重要途径。无论是跑步、游泳,还是做瑜伽,都有助于强身健体。适量的运动可以提高心肺功能,增强体力,减轻压力,提高生活质量。"}
{"index":{}}
{"content":"艺术是人类文明的重要组成部分。通过绘画、音乐、舞蹈等形式,艺术表达了人们的情感和思想。丰富多彩的艺术形式不仅带给人们美的享受,还能陶冶情操、激发创造力。"}
{"index":{}}
{"content":"环境保护是全人类共同的责任。随着工业化进程的推进,环境问题日益严重。保护环境不仅关系到我们这一代人的生活质量,也影响到后代的福祉。"}
{"index":{}}
{"content":"科学研究是推动社会进步的重要力量。通过不断的探索和实验,科学家们揭示了自然界的奥秘,为人类文明的发展提供了强大的推动力。"}
{"index":{}}
{"content":"城市化进程中,城市规划显得尤为重要。科学合理的城市规划能够提高居民的生活质量,优化资源配置,促进经济发展。"}
{"index":{}}
{"content":"文学作品是人类思想的结晶。通过阅读文学作品,人们可以了解不同的世界观和价值观,培养同理心,提升文化素养。"}
步骤五:查询数据
knn查询(稠密向量检索)
将Query转化为稠密向量进行稠密向量检索。
GET os_demo_no_split_index/_search
{
"_source": "content",
"knn" : {
"field": "content_embedding",
"query_vector_builder": {
"text_embedding": {
"model_id": "ops-text-embedding-001",
"model_text": """
AI在医疗和金融行业的应用
"""
}
},
"k": 10,
"num_candidates": 100
}
}
RRF查询(混合检索)
将Query转化为稠密向量及稀疏向量,并进行全文检索、稠密向量检索、稀疏向量检索,通过融合排序算法召回Top 10的内容。
GET os_demo_no_split_index/_search
{
"_source": "content",
"sub_searches":[
{
"query":{
"match": {
"content": "AI在医疗和金融行业的应用"
}
}
},
{
"query": {
"text_expansion":{
"content_sparse_embedding":{
"model_id":"ops-text-sparse-embedding-001",
"model_text":"AI在医疗和金融行业的应用"
}
}
}
}
],
"knn" : {
"field": "content_embedding",
"query_vector_builder": {
"text_embedding": {
"model_id": "ops-text-embedding-001",
"model_text": """
AI在医疗和金融行业的应用
"""
}
},
"k": 10,
"num_candidates": 100
},
"rank":{
"rrf":{
}
}
}
操作步骤(使用文档切片)
步骤一:(可选)调试模型
调试doc_split推理模型。
POST _inference/doc_split/ops-document-split-001 { "input":["文档切片服务(ops-document-split-001):提供通用文本切片服务,支持基于文档段落、文本语义、指定规则,对HTML、Markdown、txt格式的结构化数据进行拆分,同时支持以富文本形式提取文档中的代码、图片以及表格。OpenSearch文本向量化服务-001(ops-text-embedding-001)提供多语言(40+)文本向量化服务,输入文本最大长度300,输出向量维度1536维。"] }
调试text_embedding推理模型。
POST _inference/text_embedding/ops-text-embedding-001 { "input":["科学技术是第一生产力", "elasticsearch产品文档"] }
调试sparse_embedding推理模型。
POST _inference/sparse_embedding/ops-text-sparse-embedding-001 { "input":["科学技术是第一生产力", "elasticsearch产品文档"] }
步骤二:配置ingest pipeline
pipeline配置文档切片模型对文档进行语义切分,并应用向量化模型将切片后的文档生成text embedding向量和sparse embedding向量,写入nested类型的子文档中。
PUT _ingest/pipeline/os-pipeline-demo
{
"description": "This is an example of splitting, text-embedding and sparse-embedding fields use foreach",
"processors": [
{
"document_splitting": {
"model_id": "ops-document-split-001",
"input_output": [
{
"input_field": "content",
"output_field": "chunk",
"extend_output_field": "chunk_ext"
}
]
}
},
{
"foreach": {
"field": "chunk",
"processor": {
"text_embedding": {
"model_id": "ops-text-embedding-001",
"input_output": [
{
"input_field": "_ingest._value.content",
"output_field": "_ingest._value.embedding"
}
]
}
}
}
},
{
"foreach": {
"field": "chunk",
"processor": {
"text_embedding": {
"model_id": "ops-text-sparse-embedding-001",
"input_output": [
{
"input_field": "_ingest._value.content",
"output_field": "_ingest._value.sparse_embedding"
}
]
}
}
}
}
]
}
ingest pipeline创建成功后,可以通过simulate接口(仅用于模拟调试,不会实际创建索引),测试pipeline处理的效果::
POST _ingest/pipeline/os-pipeline-demo/_simulate
{
"docs": [
{
"_index": "testindex",
"_id": "1",
"_source":{
"content": "现代科技的发展推动了人工智能的极速进步。AI在各个领域展现出巨大的潜力,从医疗到金融,AI都在发挥着重要的作用,为人类的生活带来了翻天覆地的变化。"
}
}
]
}
步骤三:创建索引
执行以下代码,在ES中建立基于向量的文档索引。
PUT os_demo_index
{
"mappings": {
"properties": {
"content": {
"type": "text"
},
"chunk":{
"type":"nested",
"properties": {
"content":{
"type":"text"
},
"embedding":{
"type": "dense_vector",
"dims": 1536
},
"sparse_embedding":{
"type": "sparse_vector"
}
}
}
}
}
}
步骤四:写入数据
将通过pipeline处理后的数据写入索引作为搜索内容基础。
写入数据时带上配置好的pipeline_id,文本数据就可以通过pipeline进行自动的切分和embedding。
POST os_demo_index/_bulk?pipeline=os-pipeline-demo
{"index":{}}
{"content":"现代科技的发展推动了人工智能的极速进步。AI在各个领域展现出巨大的潜力,从医疗到金融,AI都在发挥着重要的作用,为人类的生活带来了翻天覆地的变化。"}
{"index":{}}
{"content":"教育是一个国家发展的基石。高质量的教育不仅能够帮助个人实现梦想,还能推动社会的进步。教育公平是实现社会和谐的关键,每个孩子都有受教育的权利。"}
{"index":{}}
{"content":"旅游可以让人们开阔视野,体验不同的文化和风俗。无论是饱览自然风光,还是探寻历史古迹,旅行都能让人们在体验中学习和成长。"}
{"index":{}}
{"content":"健康饮食对于保持身体健康至关重要。合理搭配膳食,摄入足够的营养,不仅可以增强免疫力,还能预防多种疾病。多吃蔬菜水果,少吃高脂食物,是保持健康的重要措施。"}
{"index":{}}
{"content":"互联网改变了人们的生活方式。随着智能手机和社交媒体的普及,信息传播的速度大大加快。人们可以通过网络获取最新的新闻、学习新的知识,以及与朋友保持联系。"}
{"index":{}}
{"content":"历史是一面镜子,通过研究历史,人们能够更好地了解过去,从而预测未来。无论是战争的经验教训,还是文明的更迭,历史都为我们提供了宝贵的知识和智慧。"}
{"index":{}}
{"content":"运动是保持身体健康的重要途径。无论是跑步、游泳,还是做瑜伽,都有助于强身健体。适量的运动可以提高心肺功能,增强体力,减轻压力,提高生活质量。"}
{"index":{}}
{"content":"艺术是人类文明的重要组成部分。通过绘画、音乐、舞蹈等形式,艺术表达了人们的情感和思想。丰富多彩的艺术形式不仅带给人们美的享受,还能陶冶情操、激发创造力。"}
{"index":{}}
{"content":"环境保护是全人类共同的责任。随着工业化进程的推进,环境问题日益严重。保护环境不仅关系到我们这一代人的生活质量,也影响到后代的福祉。"}
{"index":{}}
{"content":"科学研究是推动社会进步的重要力量。通过不断的探索和实验,科学家们揭示了自然界的奥秘,为人类文明的发展提供了强大的推动力。"}
{"index":{}}
{"content":"城市化进程中,城市规划显得尤为重要。科学合理的城市规划能够提高居民的生活质量,优化资源配置,促进经济发展。"}
{"index":{}}
{"content":"文学作品是人类思想的结晶。通过阅读文学作品,人们可以了解不同的世界观和价值观,培养同理心,提升文化素养。"}
步骤五:查询数据
content
、model_text
中的内容,可以替换为您想要查询的内容。
knn查询(稠密向量检索)
将Query转化为稠密向量进行稠密向量检索。
GET os_demo_index/_search
{
"_source": "content",
"knn" : {
"field": "chunk.embedding",
"query_vector_builder": {
"text_embedding": {
"model_id": "ops-text-embedding-001",
"model_text": """
AI在医疗和金融行业的应用
"""
}
},
"k": 10,
"num_candidates": 100
}
}
查询时带上inner hint,可返回knn查询命中的chunk:
GET os_demo_index/_search
{
"_source": "content",
"knn" : {
"field": "chunk.embedding",
"query_vector_builder": {
"text_embedding": {
"model_id": "ops-text-embedding-001",
"model_text": """
AI在医疗和金融行业的应用
"""
}
},
"k": 10,
"num_candidates": 100,
"inner_hits":{
"_source": ["chunk.content","chunk.meta"],
"size":2
}
}
}
RRF查询(混合检索)
将Query转化为稠密向量及稀疏向量,并进行全文检索、稠密向量检索、稀疏向量检索,通过融合排序算法召回Top 10的内容。
GET os_demo_index/_search
{
"_source": "content",
"sub_searches":[
{
"query":{
"match": {
"content": "AI在医疗和金融行业的应用"
}
}
},
{
"query":{
"nested": {
"path": "chunk",
"query": {
"text_expansion":{
"chunk.sparse_embedding":{
"model_id":"ops-text-sparse-embedding-001",
"model_text":"AI在医疗和金融行业的应用"
}
}
}
}
}
}
],
"knn" : {
"field": "chunk.embedding",
"query_vector_builder": {
"text_embedding": {
"model_id": "ops-text-embedding-001",
"model_text": """
AI在医疗和金融行业的应用
"""
}
},
"k": 10,
"num_candidates": 100
},
"rank":{
"rrf":{
}
}
}
常见问题
配置inference接口时的相关报错及解决方法:
报错信息:
"Received an unsuccessful status code for request from inference entity id [${inference_endpoint}] status [400]. Error message: [Credentials is not found]"
。解决方法:配置的api_key不存在,请检查api_key是否配置正确。
报错信息:
"Received an unsuccessful status code for request from inference entity id [${inference_endpoint}] status [400]. Error message: [service_id does not exist]"
。解决方法:配置的service_id不存在,请检查service_id是否配置正确。
报错信息:
"Invalid host [${URL}], please check that the URL is correct."
。解决方法:配置的host错误,请检查host是否配置正确。
报错信息:
"Received an unsuccessful status code for request from inference entity id [${inference_endpoint}] status [400]. Error message: [App is not found]"
。解决方法:配置的workspace错误,请检查workspace是否配置正确。